home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre1.z / postgre1 / test / postfs.usr.bin / rm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  5.3 KB  |  278 lines

  1. /*
  2.  * rm - for ReMoving files, directories & trees.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/param.h>
  7. #include <sys/stat.h>
  8. #include <sys/dir.h>
  9. #include <sys/file.h>
  10. #include "tmp/libpq-fs.h"
  11.  
  12. int    fflg;        /* -f force - supress error messages */
  13. int    iflg;        /* -i interrogate user on each file */
  14. int    rflg;        /* -r recurse */
  15.  
  16. int    errcode;    /* true if errors occured */
  17.  
  18. char    *strcpy(), *malloc(), *realloc();
  19. extern char *getenv();
  20.  
  21. main(argc, argv)
  22.     char *argv[];
  23. {
  24.     register char *arg;
  25.     char *dbname;
  26.  
  27.     if ((dbname = getenv("DATABASE")) == (char *) NULL) {
  28.         fprintf(stderr, "no database specified in env var DATABASE\n");
  29.         fflush(stderr);
  30.         exit (1);
  31.     }
  32.  
  33.     PQsetdb(dbname);
  34.  
  35.     fflg = !isatty(0);
  36.     iflg = 0;
  37.     rflg = 0;
  38.     while (argc > 1 && argv[1][0] == '-') {
  39.         arg = *++argv;
  40.         argc--;
  41.  
  42.         /*
  43.          *  all files following a null option are considered file names
  44.          */
  45.         if (arg[1] == '\0')
  46.             break;
  47.  
  48.         while (*++arg != '\0')
  49.             switch(*arg) {
  50.             case 'f':
  51.                 fflg++;
  52.                 break;
  53.  
  54.             case 'i':
  55.                 iflg++;
  56.                 break;
  57.  
  58.             case 'R':
  59.             case 'r':
  60.                 rflg++;
  61.                 break;
  62.  
  63.             default:
  64.                 fprintf(stderr, "usage: rm [-rif] file ...\n");
  65.                 PQfinish();
  66.                 exit(1);
  67.             }
  68.     }
  69.  
  70.     if (argc < 2 && !fflg) {
  71.         fprintf(stderr, "usage: rm [-rif] file ...\n");
  72.         PQfinish();
  73.         exit(1);
  74.     }
  75.  
  76.     while (--argc > 0)
  77.         (void) rm(*++argv, 0);
  78.     PQfinish();
  79.     exit(errcode != 0);
  80.     /* NOTREACHED */
  81. }
  82.  
  83. char    *path;        /* pointer to malloc'ed buffer for path */
  84. char    *pathp;        /* current pointer to end of path */
  85. int    pathsz;        /* size of path */
  86.  
  87. /*
  88.  * Return TRUE if sucessful. Recursive with -r (rflg)
  89.  */
  90. rm(arg, level)
  91.     char arg[];
  92. {
  93.     int ok;                /* true if recursive rm succeeded */
  94.     struct pgstat buf;        /* for finding out what a file is */
  95.     struct pgdirent *dp;        /* for reading a directory */
  96.     PDIR *dirp;            /* for reading a directory */
  97.     char prevname[MAXNAMLEN + 1];    /* previous name for -r */
  98.     char *cp;
  99.  
  100.     if (dotname(arg)) {
  101.         fprintf(stderr, "rm: cannot remove `.' or `..'\n");
  102.         return (0);
  103.     }
  104.     if (p_stat(arg, &buf)) {
  105.         if (!fflg) {
  106.             fprintf(stderr, "rm: ");
  107.             perror(arg);
  108.             errcode++;
  109.         }
  110.         return (0);        /* error */
  111.     }
  112.     if ((buf.st_mode&S_IFMT) == S_IFDIR) {
  113.         if (!rflg) {
  114.             if (!fflg) {
  115.                 fprintf(stderr, "rm: %s is a directory\n", arg);
  116.                 errcode++;
  117.             }
  118.             return (0);
  119.         }
  120.         if (iflg && level != 0) {
  121.             printf("rm: remove directory %s? ", arg);
  122.             if (!yes())
  123.                 return (0);    /* didn't remove everything */
  124.         }
  125.         if (/*access(arg, R_OK|W_OK|X_OK)*/ 0 != 0) {
  126.             if (p_rmdir(arg) == 0)
  127.                 return (1);    /* salvaged: removed empty dir */
  128.             if (!fflg) {
  129.                 fprintf(stderr, "rm: %s not changed\n", arg);
  130.                 errcode++;
  131.             }
  132.             return (0);        /* error */
  133.         }
  134.         if ((dirp = p_opendir(arg)) == NULL) {
  135.             if (!fflg) {
  136.                 fprintf(stderr, "rm: cannot read ");
  137.                 perror(arg);
  138.                 errcode++;
  139.             }
  140.             return (0);
  141.         }
  142.         if (level == 0)
  143.             append(arg);
  144.         prevname[0] = '\0';
  145.         while ((dp = p_readdir(dirp)) != NULL) {
  146.             if (dotname(dp->d_name)) {
  147.                 strcpy(prevname, dp->d_name);
  148.                 continue;
  149.             }
  150.             append(dp->d_name);
  151.             p_closedir(dirp);
  152.             ok = rm(path, level + 1);
  153.             for (cp = pathp; *--cp != '/' && cp > path; )
  154.                 ;
  155.             pathp = cp;
  156.             *cp++ = '\0';
  157.             if ((dirp = p_opendir(arg)) == NULL) {
  158.                 if (!fflg) {
  159.                     fprintf(stderr, "rm: cannot read %s?\n", arg);
  160.                     errcode++;
  161.                 }
  162.                 break;
  163.             }
  164.             /* pick up where we left off */
  165.             if (prevname[0] != '\0') {
  166.                 while ((dp = p_readdir(dirp)) != NULL &&
  167.                     strcmp(prevname, dp->d_name) != 0)
  168.                     ;
  169.             }
  170.             /* skip the one we just failed to delete */
  171.             if (!ok) {
  172.                 dp = p_readdir(dirp);
  173.                 if (dp != NULL && strcmp(cp, dp->d_name)) {
  174.                     fprintf(stderr,
  175.             "rm: internal synchronization error: %s, %s, %s\n",
  176.                         arg, cp, dp->d_name);
  177.                 }
  178.                 strcpy(prevname, dp->d_name);
  179.             }
  180.         }
  181.         p_closedir(dirp);
  182.         if (level == 0) {
  183.             pathp = path;
  184.             *pathp = '\0';
  185.         }
  186.         if (iflg) {
  187.             printf("rm: remove %s? ", arg);
  188.             if (!yes())
  189.                 return (0);
  190.         }
  191.         if (p_rmdir(arg) < 0) {
  192.             if (!fflg || iflg) {
  193.                 fprintf(stderr, "rm: %s not removed\n", arg);
  194.                 errcode++;
  195.             }
  196.             return (0);
  197.         }
  198.         return (1);
  199.     }
  200.  
  201.     if (iflg) {
  202.         printf("rm: remove %s? ", arg);
  203.         if (!yes())
  204.             return (0);
  205.     } else if (!fflg) {
  206.         if ((buf.st_mode&S_IFMT) != S_IFLNK && /*access(arg, W_OK)*/0 < 0) {
  207.             printf("rm: override protection %o for %s? ",
  208.                 buf.st_mode&0777, arg);
  209.             if (!yes())
  210.                 return (0);
  211.         }
  212.     }
  213.     if (p_unlink(arg) < 0) {
  214.         if (!fflg || iflg) {
  215.             fprintf(stderr, "rm: %s not removed: ", arg);
  216.             perror("");
  217.             errcode++;
  218.         }
  219.         return (0);
  220.     }
  221.     return (1);
  222. }
  223.  
  224. /*
  225.  * boolean: is it "." or ".." ?
  226.  */
  227. dotname(s)
  228.     char *s;
  229. {
  230.     if (s[0] == '.')
  231.         if (s[1] == '.')
  232.             if (s[2] == '\0')
  233.                 return (1);
  234.             else
  235.                 return (0);
  236.         else if (s[1] == '\0')
  237.             return (1);
  238.     return (0);
  239. }
  240.  
  241. /*
  242.  * Get a yes/no answer from the user.
  243.  */
  244. yes()
  245. {
  246.     int i, b;
  247.  
  248.     i = b = getchar();
  249.     while (b != '\n' && b != EOF)
  250.         b = getchar();
  251.     return (i == 'y');
  252. }
  253.  
  254. /*
  255.  * Append 'name' to 'path'.
  256.  */
  257. append(name)
  258.     char *name;
  259. {
  260.     register int n;
  261.  
  262.     n = strlen(name);
  263.     if (path == NULL) {
  264.         pathsz = MAXNAMLEN + MAXPATHLEN + 2;
  265.         if ((path = malloc(pathsz)) == NULL) {
  266.             fprintf(stderr, "rm: ran out of memory\n");
  267.             exit(1);
  268.         }
  269.         pathp = path;
  270.     } else if (pathp + n + 2 > path + pathsz) {
  271.         fprintf(stderr, "rm: path name too long: %s\n", path);
  272.         exit(1);
  273.     } else if (pathp != path && pathp[-1] != '/')
  274.         *pathp++ = '/';
  275.     strcpy(pathp, name);
  276.     pathp += n;
  277. }
  278.